package com.lysj.bhp.api.controller;

import com.lysj.bhp.approve.domain.ApproveRecord;
import com.lysj.bhp.investment.domain.Reward;
import com.lysj.bhp.util.random.FormatUtil;
import com.lysj.bhp.util.web.ParamUtil;
import com.lysj.bhp.util.web.Resp;
import com.lysj.bhp.wallet.domain.*;
import com.lysj.bhp.withdraw.base.WithdrawContent;
import com.lysj.bhp.withdraw.domain.DayLimit;
import com.lysj.bhp.withdraw.domain.Poundage;
import com.lysj.bhp.withdraw.domain.WithDraw;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api/v2/user")
@Api(value = "ApiWithdrawApplyController", tags = "提币申请接口")
public class ApiWithdrawApplyController extends WithdrawContent {

    @ApiOperation(value = "提币申请", notes = "需要提币地址,提币数量,交易密码,钱包类型,type 10:比特币;20:以太坊;100:BHPC;110:BHPC奖励金;30:比特币钻石;40:布比币;")
    @PostMapping(value = "/add_withdraw_apply")
    public Resp withdraw(String address, BigDecimal amount, String tradePassword, int type) {

        if (ParamUtil.isBlack(address)) {
            return new Resp(Resp.PARAM_ERROR, "请输入提币地址");
        }
        if (amount.compareTo(BigDecimal.ZERO) != 1) {  //提币数量小于0
            return new Resp(Resp.PARAM_ERROR, "提币数量错误");
        }
        if (ParamUtil.isBlack(tradePassword)) {
            return new Resp(Resp.PARAM_ERROR, "交易密码不能为空");
        }
        if (!ParamUtil.md5(tradePassword).equals(currentUser().getTradePassword())) {
            return new Resp(Resp.PARAM_ERROR, "交易密码有误");
        }

        WithDraw withDraw = new WithDraw();
        Poundage poundage = null;
        BigDecimal transferFee = new BigDecimal(BigInteger.ZERO);// 提币手续费默认为0
        //如果提的是bhpc,则需要查询用户的认证等级
        if (100 == type || 110 == type) {
            ApproveRecord approveRecord = approveRecordRepository.findByUserId(currentUser().getUserId());
            if (null == approveRecord) {
                poundage = poundageRepository.findByTypeAndInfoStatus(100, 0);
            } else {
                poundage = poundageRepository.findByTypeAndInfoStatus(100, approveRecord.getInfoStatus());

            }
            if ((amount.compareTo(poundage.getMaxNumber()) >= 1)) { //手续费
                return new Resp(Resp.PARAM_ERROR, "提币数量高于提币最大值,请去提高您的认证级别");
            }

        } else {
            //获取提币手续费
            poundage = poundageRepository.findByType(type);
            if ((amount.compareTo(poundage.getMaxNumber()) >= 1)) { //手续费
                return new Resp(Resp.PARAM_ERROR, "提币数量高于提币最大值");
            }
        }
        //提币数量跟手续费进行比较
        if ((amount.compareTo(poundage.getMiniNumber()) <= -1)) { //手续费
            return new Resp(Resp.PARAM_ERROR, "提币数量低于提币最小值");
        }
        //判定用户是否有未完成的提币订单
        int withAmount = withdrawRepository.countByUserIdAndTypeAndCheckStatus(currentUser().getUserId(), type, 3);
        if (withAmount >= 1) {
            return new Resp(Resp.PARAM_ERROR, "您有未完成的提币申请,请等待管理员处理,稍后再试");
        }
        //手续费
        transferFee = poundage.getTransferFee();
        ApproveRecord approveRecord = approveRecordRepository.findByUserId(currentUser().getUserId());
        //查询用户的认证等级
        int infoStatus = 0;
        if (null != approveRecord) {
            infoStatus = approveRecord.getInfoStatus();
        }
        DayLimit dayLimit;
        switch (type) {  //10:比特币;20:以太坊;100:BHPC;110:BHPC_Bouns
            case 100:
                dayLimit = dayLimitRepository.findByCoinTypeAndInfoStatus(1, infoStatus);
                //获取今日BHPC提币数额
                BigDecimal dayBhpcAmount = getBhpcAmount();
                //每日限额判定
                if (dayBhpcAmount.add(amount).compareTo(dayLimit.getAmount()) >= 1) {
                    return new Resp(Resp.PARAM_ERROR, "您的提币数额超过今日上限");
                }
                //钱包可用资产判断
                BhpcWallet bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());
                if (null == bhpcWallet) {
                    return new Resp(Resp.PARAM_ERROR, "您的BHPC数量不足");
                }
                if ((bhpcWallet.getAvailBalance().subtract(amount)).compareTo(new BigDecimal(BigInteger.ZERO)) <= -1) { //钱包的可用数额跟提币数量进行比较
                    return new Resp(Resp.PARAM_ERROR, "您的BHPC数量不足");
                }
                withDraw.setUserId(currentUser().getUserId());
                withDraw.setEmail(currentUser().getEmail());
                withDraw.setAddress(address);
                withDraw.setType(100);
                withDraw.setAmount(amount);
                withDraw.setFeeAmount(transferFee);
                withDraw.setCreateDate(new Date());
                withDraw.setStatus(0);
                withDraw.setCheckStatus(3);
                withDraw.setName("BHPC");
                withDraw.setChineseName("算力现金");

                //获取该用户的BHPC钱包,生成冻结余额,修改可用余额
                bhpcWallet.setAvailBalance((bhpcWallet.getAvailBalance().subtract(amount)));
                bhpcWallet.setFreezeBalance(bhpcWallet.getFreezeBalance().add(amount));
                bhpcWalletRepository.save(bhpcWallet);
                withdrawRepository.save(withDraw);

//                // 若提币的类型为bhpc,则自动提交转币
//                boolean result = bhpcTransactionService.submitBhpcTransactionOfPrivkey(withDraw);
//                if (result) {
//                    withDraw.setTransctionStatus(1);// 将状态改为已经提交自动转币
//                }
//                withdrawRepository.save(withDraw);
                break;
            case 110:
                dayLimit = dayLimitRepository.findByCoinTypeAndInfoStatus(2, infoStatus);
                //奖励金转btc
                BigDecimal rewardToBtc = amount.multiply(exchangeRateService.getBhpcToDollar())
                        .divide(exchangeRateService.getBitcoinToDollar(), 18, BigDecimal.ROUND_HALF_DOWN);
                //每日限额判定
                if ((rewardToBtc.add(getTodayBtcAmount())).compareTo(dayLimit.getAmount()) >= 1) {
                    return new Resp(Resp.PARAM_ERROR, "您的提币数额超过今日上限");
                }
                Reward rewardWallet = rewardRepository.findByUserIdAndType(currentUser().getUserId(), 100);
                if (null == rewardWallet) {
                    return new Resp(Resp.PARAM_ERROR, "您的BHPC奖励数量不足");
                }

                if ((rewardWallet.getAvailBalance().subtract(amount)).compareTo(new BigDecimal(BigInteger.ZERO)) <= -1) {
                    return new Resp(Resp.PARAM_ERROR, "您的BHPC奖励数量不足");
                }
                withDraw.setUserId(currentUser().getUserId());
                withDraw.setEmail(currentUser().getEmail());
                withDraw.setAddress(address);
                withDraw.setType(110);
                withDraw.setAmount(amount);
                withDraw.setFeeAmount(transferFee);
                withDraw.setCreateDate(new Date());
                withDraw.setStatus(0);
                withDraw.setCheckStatus(3);
                withDraw.setName("BHPC");
                withDraw.setChineseName("算力现金");
                //获取该用户的BHPC奖励钱包,生成冻结余额,修改可用余额
                rewardWallet.setAvailBalance(rewardWallet.getAvailBalance().subtract(amount));
                rewardWallet.setFreezeBalance(rewardWallet.getFreezeBalance().add(amount));
                rewardRepository.save(rewardWallet);
                withdrawRepository.save(withDraw);
                break;
            case 10:
                dayLimit = dayLimitRepository.findByCoinTypeAndInfoStatus(2, infoStatus);

                //每日限额判定
                if ((amount.add(getTodayBtcAmount())).compareTo(dayLimit.getAmount()) >= 1) {
                    return new Resp(Resp.PARAM_ERROR, "您的提币数额超过今日上限");
                }
                BitCoinWallet bitCoinWallet = bitcoinWalletRepository.findByUserId(currentUser().getUserId());
                if (null == bitCoinWallet) {
                    return new Resp(Resp.PARAM_ERROR, "您的BTC数量不足");
                }

                if ((bitCoinWallet.getAvailBalance().subtract(amount)).compareTo(new BigDecimal(BigInteger.ZERO)) <= -1) { //手续费
                    return new Resp(Resp.PARAM_ERROR, "您的BTC数量不足");
                }

                withDraw.setUserId(currentUser().getUserId());
                withDraw.setEmail(currentUser().getEmail());
                withDraw.setAddress(address);
                withDraw.setType(10);
                withDraw.setAmount(amount);
                withDraw.setFeeAmount(transferFee); //需要修改
                withDraw.setCreateDate(new Date());
                withDraw.setStatus(0);
                withDraw.setCheckStatus(3);
                withDraw.setName("BTC");
                withDraw.setChineseName("比特币");
                //获取该用户的BHPC钱包,生成冻结余额,修改可用余额
                bitCoinWallet.setAvailBalance(bitCoinWallet.getAvailBalance().subtract(amount));
                bitCoinWallet.setFreezeBalance(bitCoinWallet.getFreezeBalance().add(amount));
                bitcoinWalletRepository.save(bitCoinWallet);
                withdrawRepository.save(withDraw);
                break;
            case 20:
                dayLimit = dayLimitRepository.findByCoinTypeAndInfoStatus(2, infoStatus);
                //奖励金转btc
                BigDecimal ethToBtc = amount.multiply(exchangeRateService.getEthereumToDollar())
                        .divide(exchangeRateService.getBitcoinToDollar(), 18, BigDecimal.ROUND_HALF_DOWN);
                //每日限额判定
                if ((ethToBtc.add(getTodayBtcAmount())).compareTo(dayLimit.getAmount()) >= 1) {
                    return new Resp(Resp.PARAM_ERROR, "您的提币数额超过今日上限");
                }
                EthereumWallet ethereumWallet = ethereumWalletRepository.findByUserId(currentUser().getUserId());
                if (null == ethereumWallet) {
                    return new Resp(Resp.PARAM_ERROR, "您的ETH数量不足");
                }

                if ((ethereumWallet.getAvailBalance().subtract(amount)).compareTo(new BigDecimal(BigInteger.ZERO)) <= -1) { //手续费
                    return new Resp(Resp.PARAM_ERROR, "您的ETH数量不足");
                }
                withDraw.setUserId(currentUser().getUserId());
                withDraw.setEmail(currentUser().getEmail());
                withDraw.setAddress(address);
                withDraw.setType(20);
                withDraw.setAmount(amount);
                withDraw.setFeeAmount(transferFee);
                withDraw.setCreateDate(new Date());
                withDraw.setStatus(0);
                withDraw.setCheckStatus(3);
                withDraw.setName("ETH");
                withDraw.setChineseName("以太坊");
                //获取该用户的BHPC钱包,生成冻结余额,修改可用余额
                ethereumWallet.setAvailBalance((ethereumWallet.getAvailBalance().subtract(amount)));
                ethereumWallet.setFreezeBalance(ethereumWallet.getFreezeBalance().add(amount));
                ethereumWalletRepository.save(ethereumWallet);
                withdrawRepository.save(withDraw);
                break;
            case 30:
                dayLimit = dayLimitRepository.findByCoinTypeAndInfoStatus(2, infoStatus);
                //奖励金转btc
                BigDecimal bcdToBtc = amount.multiply(exchangeRateService.getDiamoundToDollar())
                        .divide(exchangeRateService.getBitcoinToDollar(), 18, BigDecimal.ROUND_HALF_DOWN);
                //每日限额判定
                if ((bcdToBtc.add(getTodayBtcAmount())).compareTo(dayLimit.getAmount()) >= 1) {
                    return new Resp(Resp.PARAM_ERROR, "您的提币数额超过今日上限");
                }
                DiamondBitcoinWallet diamondBitcoinWallet = diamondBitcoinWalletRepository.findByUserId(currentUser().getUserId());
                if (null == diamondBitcoinWallet) {
                    return new Resp(Resp.PARAM_ERROR, "您的BCD数量不足");
                }

                if ((diamondBitcoinWallet.getAvailBalance().subtract(amount)).compareTo(new BigDecimal(BigInteger.ZERO)) <= -1) { //手续费
                    return new Resp(Resp.PARAM_ERROR, "您的BCD数量不足");
                }
                withDraw.setUserId(currentUser().getUserId());
                withDraw.setEmail(currentUser().getEmail());
                withDraw.setAddress(address);
                withDraw.setType(30);
                withDraw.setAmount(amount);
                withDraw.setFeeAmount(transferFee);
                withDraw.setCreateDate(new Date());
                withDraw.setStatus(0);
                withDraw.setCheckStatus(3);
                withDraw.setName("BCD");
                withDraw.setChineseName("比特钻石");
                //获取该用户的BHPC钱包,生成冻结余额,修改可用余额
                diamondBitcoinWallet.setAvailBalance((diamondBitcoinWallet.getAvailBalance().subtract(amount)));
                diamondBitcoinWallet.setFreezeBalance(diamondBitcoinWallet.getFreezeBalance().add(amount));
                diamondBitcoinWalletRepository.save(diamondBitcoinWallet);
                withdrawRepository.save(withDraw);
                break;
            case 40:
                dayLimit = dayLimitRepository.findByCoinTypeAndInfoStatus(2, infoStatus);
                //奖励金转btc
                BigDecimal buToBtc = amount.multiply(exchangeRateService.getBuToDollar())
                        .divide(exchangeRateService.getBitcoinToDollar(), 18, BigDecimal.ROUND_HALF_DOWN);
                //每日限额判定
                if ((buToBtc.add(getTodayBtcAmount())).compareTo(dayLimit.getAmount()) >= 1) {
                    return new Resp(Resp.PARAM_ERROR, "您的提币数额超过今日上限");
                }

                BuWallet buWallet = buWalletRepository.findByUserId(currentUser().getUserId());
                if (null == buWallet) {
                    return new Resp(Resp.PARAM_ERROR, "您的BU数量不足");
                }

                if ((buWallet.getAvailBalance().subtract(amount)).compareTo(new BigDecimal(BigInteger.ZERO)) <= -1) { //手续费
                    return new Resp(Resp.PARAM_ERROR, "您的BU数量不足");
                }
                withDraw.setUserId(currentUser().getUserId());
                withDraw.setEmail(currentUser().getEmail());
                withDraw.setAddress(address);
                withDraw.setType(40);
                withDraw.setAmount(amount);
                withDraw.setFeeAmount(transferFee);
                withDraw.setCreateDate(new Date());
                withDraw.setStatus(0);
                withDraw.setCheckStatus(3);
                withDraw.setName("BU");
                withDraw.setChineseName("布");
                //获取该用户的BHPC钱包,生成冻结余额,修改可用余额
                buWallet.setAvailBalance((buWallet.getAvailBalance().subtract(amount)));
                buWallet.setFreezeBalance(buWallet.getFreezeBalance().add(amount));
                buWalletRepository.save(buWallet);
                withdrawRepository.save(withDraw);
                break;
            default:
                return new Resp(Resp.PARAM_ERROR, "提币类型错误");
        }
        return new Resp("提币申请成功");
    }


     /**
      * @author drj
      * @date 2018/9/13 16:05
      * @Description:今日BHPC提币数量
      */
    private BigDecimal getBhpcAmount() {
        Integer[] checkStatus = new Integer[2];
        checkStatus[0] = 1; //提币完成
        checkStatus[1] = 3; //未审核
        Date beginDate = FormatUtil.getDayStartDay(new Date());//今日 0:0:0
        Date endDate = FormatUtil.getDayEndDay(new Date()); //今日 23:59:59
        BigDecimal amount = new BigDecimal(BigInteger.ZERO);
        List<WithDraw> withDrawList = withdrawRepository.findByUserIdAndTypeAndCheckStatusInAndCreateDateBetween(currentUser().getUserId(), 100, checkStatus, beginDate, endDate);
        for (WithDraw withDraw : withDrawList) {
            amount = amount.add(withDraw.getAmount());
        }
        return amount;
    }


    /**
     * @author drj
     * @date 2018/9/13 15:47
     * @Description:今日其他币种的提币数额
     */
    private BigDecimal getTodayBtcAmount() {
        //今日提的BTC总额
        BigDecimal btcAmount = toBtcAmount(10, exchangeRateService.getBitcoinToDollar());
        //今日提的reward总额
        BigDecimal rewardAmount = toBtcAmount(110, exchangeRateService.getBhpcToDollar());
        //今日提的ETH总额
        BigDecimal ethAmount = toBtcAmount(20, exchangeRateService.getEthereumToDollar());
        //今日提的BCD总额
        BigDecimal bcdAmount = toBtcAmount(30, exchangeRateService.getDiamoundToDollar());
        //今日提的BU总额
        BigDecimal buAmount = toBtcAmount(40, exchangeRateService.getBhpcToDollar());

        return btcAmount.add(rewardAmount).add(ethAmount).add(bcdAmount).add(buAmount);
    }


    private BigDecimal toBtcAmount(int type, BigDecimal exchangeRate) {
        Integer[] checkStatus = new Integer[2];
        checkStatus[0] = 1; //提币完成
        checkStatus[1] = 3; //未审核
        Date beginDate = FormatUtil.getDayStartDay(new Date());//今日 0:0:0
        Date endDate = FormatUtil.getDayEndDay(new Date()); //今日 23:59:59
        BigDecimal btcAmount = new BigDecimal(BigInteger.ZERO);
        //今日的BTC提币记录
        List<WithDraw> btcWithDrawList = withdrawRepository.findByUserIdAndTypeAndCheckStatusInAndCreateDateBetween(currentUser().getUserId(), type, checkStatus, beginDate, endDate);
        for (WithDraw withDraw : btcWithDrawList) {
            btcAmount = btcAmount.add(withDraw.getAmount().multiply(exchangeRate)
                    .divide(exchangeRateService.getBitcoinToDollar(), 18, BigDecimal.ROUND_DOWN));
        }
        return btcAmount;
    }
}
